<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
</body>
<script>
    // 构造函数
    function Star(uname, age) {
        this.uname = uname;
        this.age = age;
    }
    Star.prototype.sing = function () {
        console.log(this.uname + '会唱歌');
    }
    Star.sex = '刘德华'; //静态成员
    Star.sing = function () { //静态成员//静态成员//静态成员
        console.log('我是静态方法', this.sex); //静态方法只有访问静态成员，不可访问动态成员
    }
    const ldh = new Star('西洋蔡', 20);
    ldh.sing();
    Star.sing();
    console.log(Star.sex);
    // 注意：静态资源不能用实例对象访问，只能通过构造函数访问，相反，动态成员也是只有实例对象才能访问；

    // 注意：构造函数与类不能同名

    // 类
    class Allstar {
        constructor(uname, age) {
            this.uname = uname;
            this.age = age;
        }
    }
    Allstar.prototype.sing = function () {
        console.log(this.uname + '会唱歌'); //静态方法只有访问静态成员，不可访问动态成员
    }
    Allstar.sex = '张学友'; //静态成员
    Allstar.sing = function () { //静态成员
        console.log('我是静态方法', this.sex);
    }
    const zxy = new Allstar('奀妹', 28);
    const zxc = new Allstar('上下九', 18);
    zxy.sing();
    console.log(zxy.sing === zxc.sing);
    // console.log(Allstar.sex);
    // 注意：静态资源不能用实例对象访问，只能通过构造函数访问，相反，动态成员也是只有实例对象才能访问；
    Allstar.sing();
    console.log(zxy);
    
    // // 结合闭包与promise的案例
    // const tasks = []; // 这里存放异步操作的 Promise
    // const output = (i) => new Promise((resolve) => {
    //     setTimeout(() => {
    //         console.log(new Date, i);
    //         resolve();
    //     }, 1000 * i);
    // });

    // // 生成全部的异步操作
    // for (var i = 0; i < 5; i++) {
    //     tasks.push(output(i));
    // }

    // // 异步操作完成之后，输出最后的 i
    // Promise.all(tasks).then(() => {
    //     setTimeout(() => {
    //         console.log(new Date, i);
    //     }, 1000);
    // });

    const info = {name: '森林',age: 30};
    const newInfo = JSON.stringify(info,null,5)
    // JSON.stringify的三个参数
    // json: 必须，可以是数组或Object
    // replacer: 可选值，可以是数组，也可以是方法
    // space: 用什么来进行分隔
    // console.log(newInfo);
    

    // if (status === 'process' || status === 'wait' || status === 'fail') {
    // doSomething()
    // }  //像这种冗余的判断条件可以简化为以下两种

    // 第一种
    // let status = 'wait';
    function doSomething(str='succeese'){
        console.log(str);
    }
    // switch(status) {
    // case 'process':
    // case 'wait':
    // case 'fail':
    // doSomething(status)
    // }

    // 第二种
    const enums = ['process', 'wait', 'fail']
    let status = 'process';
    if (enums.includes(status)) {
    doSomething(status)
    }

    // 取两个数组的相同项
    const arr1 = [1,6, 2, 3, 4, 5 , 8 ,9,7],arr2 = [5, 6, 7, 8, 9,10,11],arr3 = [1,2,7,3,6,8,9];
	
    // 第一种方法：
    // 	const empty = []
    // 	arr3.forEach((val,index) => {
    // 		if (arr2.includes(val)&&arr1.includes(val)) {
    // 			empty.push(val)
    // 		}
    // 	})
    //     empty.sort((a,b)=>{
    //         return a-b;
    //     })
    //    console.log(empty)

    // 第二种方法
    // const intersection = arr1.filter(function (val) { return arr2.indexOf(val) > -1 }).filter(function (val) { return arr3.indexOf(val) > -1 }).sort(function (a,b){return a-b})
    // console.log(intersection) //[5, 6, 8, 9]

    // 数组去重
    // const result = arr1.concat(arr2.filter(v => !arr1.includes(v)))
    // console.log(result)

    // 数组arr1相对于arr2所没有的 
    // const diff = arr1.filter(item => !new Set(arr2).has(item))
    // console.log(diff)

    // 两个数组各自没有的集合
    // const difference = Array.from(new Set(arr1.concat(arr2).filter(v => !new Set(arr1).has(v) || !new Set(arr2).has(v)))) 
    // console.log(difference)//[1, 2, 3, 4, 10, 11]


    const obj = {name: 'curry',age: 18},obj2 = {name: 'KD',age: 28};
    // const newArr = Object.keys(obj);  // 对象的属性名,即(key),合并为一个数组
    // console.log(newArr);

    // const newArr = Object.values(obj);  // 对象的属性值,即(value),合并为一个数组
    // console.log(newArr);

    // 把多个对象放进一个数组里
    // const arr = [];
    // arr.push(obj,obj2);
    // console.log(arr);

    // 对象多余属性删除
    // const { name, age, ...objs } = { name: '张三', age: 13, dec: '描述1', info: '信息' }
    // console.log(objs);

    // 函数的隐式返回值
    // const anonymous = (()=>3)();
    // const ano= (()=>{
    //   return 8  
    // })()
    // console.log(anonymous,ano);

    // const num = 0.1 + 0.2;
    // console.log(num);//0.30000000000000004;  0.1+0.2不等于0.3


    // 使用工厂模式创建对象
    // 1.创建一个函数  工厂函数
    // function CreatePerson(name,age,gender){
    //     // 2.使用构造函数创建一个模板实例
    //     const person=new Object();
    //     // 3.给模板实例赋值
    //     person.name=name;
    //     person.age=age;
    //     person.gender=gender;
    //     person.sayName=function(){
    //         console.log(this.name);
    //     }
    //     // 4.返回一个实例对象
    //     return person;
    // }
    // const personal = CreatePerson('curry',30,'man');
    // console.log(personal);

    // 合并对象
    // const objs1 = {name: '李三'},objs2 = {id:'渣男'},objs3 = {sex:'张三'}
    // console.log({...objs1,...objs2,...objs3});

    // const objs = {name: 'curry',id: 30}
    // console.log('kd' in objs);//判断指定的属性在指定的对象或其原型链中上面有没有，有则返回true，没有返回false;
    // console.log(objs.hasOwnProperty('kd'));//只判断自身对象上有没有指定的属性

    // 数组扁平化（嵌套多层的都可以）
    // const arr = [1,[2,3,[4,5,[6,7,[8,9]]]]]
    // function flatten(arr) {
    // while(arr.some(item=>Array.isArray(item))) {
    //     arr = [].concat(...arr);
    // }
    //     return arr;
    // }
    // console.log(flatten(arr));

    // console.log(arr.flat(Infinity));//第二种方法（嵌套多层也可）


    for (let i = 0; i < 10; i++) {  //这个符合了闭包的条件所以是闭包：函数作为参数被传递
    let li = document.createElement('li')
    li.innerHTML = i
    li.addEventListener('click', function (e) {  //这里的这个函数就是作为参数被传递
        e.preventDefault()
        alert(i)
    })
    document.body.appendChild(li)
    }


    // const objs2 = {
	// name: 'Jine',
	// get age() { return '18' }
    // };
    // console.log(Object.getOwnPropertyDescriptors(objs2));//返回objs2对象的所有自身属性的描述符，如果没有任何自身属性，则返回空对象。

    // const num = 8;
    // if(!(num & 1)){ //判断是否为偶数
    //     console.log('我是偶数');
    // }
</script>

</html>